/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkRtmpPlayer.h"
#include "MkUtil/MkLog.h"
#include "MkFlv/MkFlvDemuxer.h"

CMkRtmpPlayer::CMkRtmpPlayer(CMkEvent* pEvent, CMkTimer* pTimer, const MkEventRemovedCallback& RemoveCb)
    : CMkRtmpClient(pEvent, pTimer, RemoveCb)
    , CMkMediaSource(MkMediaSourceRtmpPlayer)
{

}

Uint32 CMkRtmpPlayer::OnHandSharked()
{
    return SendConnect(FALSE);
}

Uint32 CMkRtmpPlayer::OnConnectResult(BOOL bSuccess)
{
    if (bSuccess) {
        SendWindownAcknowledgementSize();
        SendCreateStream();
    } else {
        Close();
        if (m_ResultCb) {
            m_ResultCb(this, UnknownError);
        }
        return SocketClosed;
    }
    return NoneError;
}

Uint32 CMkRtmpPlayer::OnCreateStreamResult(BOOL bSuccess)
{
    if (bSuccess) {
        SendGetStreamLength();
        SendPlay();
        //SendAcknowledgement(5000000);
    } else {
        if (m_ResultCb) {
            m_ResultCb(this, UnknownError);
        }
        Close();
        return SocketClosed;
    }
    return NoneError;
}

Uint32 CMkRtmpPlayer::OnAudio(const Uint8* pBuf, Uint32 nLen, Uint32 TimeStamp)
{
    //MkDebugLog("onaudio\n");
    MkEsPacket EsPacket;
    Uint32 ErrorCode = CMkFlvDemuxer::AudioTagParse(pBuf, nLen, TimeStamp, FALSE, m_AudioParam, EsPacket);
    MkCheckErrorLog(ErrorCode, "parse audio failed\n");
    if (MkCodecUnknown != EsPacket.CodecType) {
        OnReadEsPacket(EsPacket);
    }
    return NoneError;
}

Uint32 CMkRtmpPlayer::OnVideo(const Uint8* pBuf, Uint32 nLen, Uint32 TimeStamp)
{
    MkEsPacket EsPacket;
    Uint32 ErrorCode = CMkFlvDemuxer::VideoTagParse(pBuf, nLen, TimeStamp, TRUE, m_VideoParam, EsPacket);
    MkCheckErrorLog(ErrorCode, "parse video failed\n");
    if (MkCodecUnknown != EsPacket.CodecType) {
        OnReadEsPacket(EsPacket);
    }
    return NoneError;
}

Uint32 CMkRtmpPlayer::OnMetaData(const MkVector<MkAmfObject>& VecObj)
{
    Uint32 Width = 0;
    Uint32 Height = 0;
    Uint32 VideoBitRate = 0;
    Uint32 FrameRate = 0;
    Uint8 VideoCodecType = MkVideoRtmpUnknow;
    Uint8 AudioCodeType = MkAudioRtmpUnknow;
    Uint32 AudioBitRate = 0;
    Uint32 AudioSampleRate = 0;
    Uint32 AudioSampleSize = 0;
    BOOL bStereo = FALSE;
    CMkFlvDemuxer::AmfObjectParse(VecObj, Width, Height, VideoBitRate, FrameRate, VideoCodecType, AudioCodeType, AudioBitRate, AudioSampleRate, AudioSampleSize, bStereo, m_Duration, m_FileSize);
    m_VideoParam.SetCodec(CMkMediaUtil::RtmpVideoTypeToCodec((MkRtmpVideoType)VideoCodecType));
    m_VideoParam.SetWidth(Width);
    m_VideoParam.SetHeight(Height);
    m_VideoParam.SetFrameRate(FrameRate);
    m_VideoParam.SetBitRate(VideoBitRate);
    m_AudioParam.SetCodec(CMkMediaUtil::RtmpAudioTypeToCodec((MkRtmpAudioType)AudioCodeType));
    m_AudioParam.SetBitRate(AudioBitRate);
    m_AudioParam.SetSampletRate(CMkMediaUtil::AudioSampleRateToIndex(AudioSampleRate));
    m_AudioParam.SetSampleSize(CMkMediaUtil::AudioSampleSizeToIndex(AudioSampleSize));
    m_AudioParam.SetStereo(bStereo);
    if (m_ResultCb) {
        m_ResultCb(this, NoneError);
    }
    return NoneError;
}

Uint32 CMkRtmpPlayer::StartMediaSource(const MkString& RtmpUrl, const MkSourceResultCallback& ResultCb, const MkEsPacketCallback& EsCb /* = nullptr */)
{
    CMkMediaSource::StartMediaSource(ResultCb, EsCb);
    return ConnectUrl(RtmpUrl);
}

Uint32 CMkRtmpPlayer::StopMediaSource()
{
    return Close();
}

CMkRtmpPlayer::~CMkRtmpPlayer()
{

}